package org.deft.tween {

	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;

	/**
	 * 按照加入的顺序播放一组DTween动画
	 * 播放完成一个后播放下一个
	 *
	 */
	public class DTweenQueue extends EventDispatcher {
		//存储DTweenQueue实例化的对象，防止被垃圾回收
		private static var tweenDic:Dictionary = new Dictionary();

		private var items:Array;
		private var item:TweenItem;
		private var index:int;

		/**
		 * 所有动画播放完需要的总时间
		 * @return
		 *
		 */
		public function get duration():Number {
			var p:Number = 0;
			for each (var i:TweenItem in items) {
				p += i.tween.duration;
			}
			return p;
		}

		public function DTweenQueue() {
			items = [];
			index = 0;
			tweenDic[this] = this;
		}

		/**
		 * 增加一个tween到队列中
		 * @param tween
		 * @param motionChanged DTweenEvent.MOTION_CHANGE的侦听函数
		 * @param motionFinished DTweenEvent.MOTION_FINISH的侦听函数
		 *
		 */
		public function add(tween:DTween, motionChanged:Function = null, motionFinished:Function = null):void {
			tween.stop();
			items.push(new TweenItem(tween, motionChanged, motionFinished));
			tween.addEventListener(DTweenEvent.MOTION_FINISH, onFinishOne, false, 0, true);
			tween.addEventListener(DTweenEvent.MOTION_CHANGE, onMotionChange, false, 0, true);
		}

		/**
		 * 从头开始播放这组动画
		 *
		 */
		public function start():void {
			index = 0;
			next();
		}

		/**
		 * 停止播放
		 *
		 */
		public function stop():void {
			if (item) {
				item.tween.stop();
			}
		}

		/**
		 * 暂停播放
		 *
		 */
		public function pause():void {
			if (item) {
				item.tween.pause();
			}
		}

		/**
		 * 暂停后，用这个方法恢复播放
		 *
		 */
		public function resume():void {
			if (item) {
				item.tween.resume();
			}
		}


		private function onFinishOne(e:DTweenEvent):void {
			index++;
			next();
		}

		private function next():void {
			if (index >= 0 && index < items.length) {
				item = items[index];
				item.tween.start();
			} else {
				dispatchEvent(new DTweenEvent(DTweenEvent.MOTION_FINISH_ALL));
			}
		}

		/**
		 * 获取当前处于播放中或播放完成的DTween对象.如果返回null，则说明还没开始播放
		 * @return
		 *
		 */
		public function getCurrentTween():DTween {
			return item == null ? null : item.tween;
		}

		private function onMotionChange(e:DTweenEvent):void {
			dispatchEvent(new DTweenEvent(DTweenEvent.MOTION_CHANGE));
		}

		public function disable():void {
			for (var i:int = 0; i < items.length; i++) {
				var item:TweenItem = items[i];
				item.changeCallback = null;
				item.finishedCallback = null;
				item.tween.disable();
			}
			items = [];
			index = 0;
			delete tweenDic[this];
		}
	}
}

import org.deft.tween.DTween;
import org.deft.tween.DTweenEvent;

class TweenItem {

	public var tween:DTween;
	public var changeCallback:Function;
	public var finishedCallback:Function;

	public function TweenItem(tween:DTween, motionChanged:Function = null, motionFinished:Function = null) {
		this.tween = tween;
		this.changeCallback = motionChanged;
		this.finishedCallback = motionFinished;
		tween.addEventListener(DTweenEvent.MOTION_CHANGE, onMotionChange, false, 0, true);
		tween.addEventListener(DTweenEvent.MOTION_FINISH, onMotionFinished, false, 0, true);
	}

	private function onMotionChange(e:DTweenEvent):void {
		if (changeCallback != null)
			changeCallback(e);
	}

	private function onMotionFinished(e:DTweenEvent):void {
		if (finishedCallback != null)
			finishedCallback(e);
	}
}
